	function BFMain(wi, hi)
	{
		Resizable.call(this);
		this.w = wi;
		this.h = hi;
		
		this.game = new Controller(wi, hi);
		this.game.addEventListener2("over", this.over, this);
		this.addChild(this.game);
		
		this.panel = new Panel();
		this.panel.pbtn.addEventListener2(MouseEvent.CLICK, this.goPlay, this);
		this.addChild(this.panel);
		this.panel.y = hi*1.5;
		this.panel.Show((hi-300)/2);
		
		this.auth = new CText("Ivan Kuckir", 5);
		this.auth.x = 20;
		this.addChild(this.auth);
	}
	BFMain.prototype = new Resizable();
	
	BFMain.prototype.resize = function(wi, hi)
	{
		Resizable.prototype.resize.call(this, wi, hi);
		
		this.game.resize(wi, hi);
		
		this.auth.y = hi-20-this.auth.GetHeight();
		
		this.panel.x = (wi-541)*0.5;
		if(!this.panel.hidden) this.panel.y = (hi-this.panel.GetHeight())*0.5;
		else this.panel.y = hi+200;
	}
	
	BFMain.prototype.over = function(e)
	{
		this.panel.Show((this.h-300)/2);
	}
	
	BFMain.prototype.goPlay = function(e)
	{
		this.panel.Hide(this.h+100);
		this.game.Start();
	}
	
	
	
	function Background(wi, hi)
	{
		Resizable.apply(this);
		this.w = wi;
		this.h = hi;
		this.bg;
		this.bubbles = [];
		this.corals = [];
		this.t = 0;
		
		this.mouseChildren = false;
		this.mouseEnabled = false;
	
		
		var bd = new BitmapData("bf_pics/blue_bg.jpg");
		bd.loader.addEventListener2(Event.COMPLETE, this.onBDLoaded, this);
		this.bg = new Bitmap(bd);
		
		this.addChild(this.bg);
		
		this.stuff = new Sprite();
		this.addChild(this.stuff);
		
		var bbd = new BitmapData("bf_pics/bubble.png");
		for(var i=0; i<20; i++)
		{
			var b = new Bitmap(bbd);
			this.bubbles.push(b);
			this.stuff.addChild(b);
			b.x = -wi/2 + Math.random()*wi;
			b.y = -hi/2 + Math.random()*hi;
			b.scaleX = b.scaleY = 0.14+Math.random()*0.4;
			b.alpha = 0.1+0.5*b.scaleX;
		}
		
		var cbd = new BitmapData("bf_pics/coral.png");
		for(var i=0; i<10; i++)
		{
			var b = new Bitmap(cbd);
			this.corals.push(b);
			this.stuff.addChild(b);
			b.y = 140 + 80*(i%4);
			b.alpha = 0.4 + ((i%2==0)?0:0.25);
			b.scaleX = b.scaleY = 1.4+Math.random()*((i%2==0)?0.7:0.4);
		}
		
		this.addEventListener2(Event.ENTER_FRAME, this.onEF, this);
	}
	Background.prototype = new Resizable();
	
	Background.prototype.resize = function(wi, hi)
	{
		var wsc = wi/this.w;
		Resizable.prototype.resize.call(this, wi, hi);
		this.bg.SetWidth(wi);
		this.bg.SetHeight(hi);
		this.stuff.x = wi/2;
		this.stuff.y = hi/2;
	}
	
	Background.prototype.onBDLoaded = function(e)
	{
		this.resize(this.w, this.h);
	}
	
	Background.prototype.UpdateScale = function(sc)
	{
		Tweener.addTween(this.stuff, {scaleX:sc, scaleY:sc, transition:"easeInOutSine", time:1 });
		//this.bg.UpdateScale(sc);
	}
	
	Background.prototype.onEF = function(e)
	{
		var th = e.target;
		++th.t;
		var sc = 1/this.stuff.scaleX;
		for(var i=0; i<th.bubbles.length; i++)
		{
			var b = th.bubbles[i];
			b.y -= 10*b.scaleX*b.scaleX;
			if(b.y < -(0.5*this.h*sc)) 
			{
				b.y = 0.5*this.h*sc;
				b.x = (-0.5*th.w + Math.random()*th.w)*sc;
			}
		}
		var cx;
		var coef = 0.1*th.w*1.05
		for(var i=0; i<th.corals.length; i++)
		{
			var b = th.corals[i];
			cx = -0.7*this.w + i*coef;
			b.x = cx + Math.sin((cx*0.15+th.t)*0.02)*50;
		}
	}
	
	function View(model)
	{
		Sprite.call(this);
		
		this.model = model;
		
		this.mfish = new Fish();
		this.addChild(this.mfish);
		this.fishes = [];
		
		for(var i=0; i<model.nof; i++)
		{
			var f = new Fish();
			this.fishes.push(f);
			this.addChild(f);
		}
		
	}
	View.prototype = new Sprite();
	
	View.prototype.Update = function()
	{
		var m = this.model;
		this.mfish.x = m.mfish.x;
		this.mfish.y = m.mfish.y;
		this.mfish.UpdateRadDir(m.mfish.rad, 1);
		this.mfish.update();
		
		for(var i=0; i<m.fishes.length; i++)
		{
			var f = this.fishes[i];
			f.update();
			var mf = m.fishes[i];
			f.x = mf.x;
			f.y = mf.y;
			f.UpdateRadDir(mf.rad, mf.dir.x);
		}
	}
	
	

	function Model()
	{
		this.nof	= 20;			// number of fish
		this.ffr	= 10;			// first fish length
		this.acoeff	= 4000;			// map area / fish rad ^2  coefficient
		this.area	= 0;
		this.bArea	= 0;
		this.w2h	= 1;
		this.maprx	= 0;
		this.mapry	= 0;
		this.over	= false;
		this.sizeChanged = false;
		
		this.mfish = new MFish();
		this.fishes = [];
		
		for(var i=0; i<this.nof; i++)  this.fishes.push(new MFish());
	}
	
	Model.prototype.Reset = function()
	{
		this.area = this.bArea = this.ffr*this.ffr*this.acoeff;
		this.updateMapSize();
		this.mfish.SetRad(this.ffr);
		this.mfish.x = this.mfish.y = 0;
		
		for(var i=0; i<this.nof; i++) this.ResetFish(i);
	}
	
	Model.prototype.IsOver = function()
	{
		var over = this.over;
		this.over = false;
		return over;
	}
	
	Model.prototype.SizeChanged = function()
	{
		var sc = this.sizeChanged;
		this.sizeChanged = false;
		return sc;
	}
	
	Model.prototype.SetFishPos = function(x, y)
	{
		this.mfish.x = x;
		this.mfish.y = y;
	}
	
	Model.prototype.Step = function()
	{
		var mx = this.mfish.x;
		var my = this.mfish.y;
		var mr = this.mfish.rad;
		var brdr = this.mfish.rad*4;
		
		if(mr*mr*this.acoeff / this.bArea > 4)
		{
			this.bArea*= 4;
			this.area *= 2;
			this.updateMapSize();
			this.sizeChanged = true;
		}
		
		for(var i=0; i<this.fishes.length; i++)
		{
			var f = this.fishes[i];
			
			var rdx = 0.14*mr*(0.5+0.5*Math.random());
			var rdy = 0.14*mr*(0.5+0.5*Math.random());
			var sgn = Math.random()>0.5?1:-1;
			if(f.x < -this.maprx-brdr)		{f.SetDir( rdx, sgn*rdy);	f.SetRad(Model.around(mr));}
			else if(f.x > this.maprx+brdr)	{f.SetDir(-rdx, sgn*rdy);	f.SetRad(Model.around(mr));}
			if(f.y < -this.mapry-brdr)		{f.SetDir(sgn*rdx,  rdy);	f.SetRad(Model.around(mr));}
			else if(f.y > this.mapry+brdr)	{f.SetDir(sgn*rdx, -rdy);	f.SetRad(Model.around(mr));}
			
			if(Point.distance(this.mfish, f)< (mr+f.rad))
			{
				if(f.rad > mr) this.over = true;
				else 
				{
					this.mfish.AddToRad(f.rad*0.08);
					this.ResetFish(i);
				}
			}
			f.x += f.dir.x;
			f.y += f.dir.y;
		}
	}
	
	Model.prototype.ResetFish = function(i)
	{
		var f = this.fishes[i];
		
		f.SetRad(Model.around(this.mfish.rad));
		
		var mr = this.mfish.rad;
		var rdx = 0.14*mr*(0.5+0.5*Math.random());
		var rdy = 0.14*mr*(0.5+0.5*Math.random());

		if(Math.random()<0.5)	f.x = -this.maprx;
		else 					f.x =  this.maprx;
		
		f.SetDir(rdx, rdy)
		f.y = -this.mapry + 2*Math.random()*this.mapry;
	}
	
	Model.prototype.SetSizeRatio = function(w2h)
	{
		this.w2h = w2h;
		this.updateMapSize();
	}
	Model.prototype.updateMapSize = function()
	{
		this.mapry = 0.5 * Math.sqrt(this.area / this.w2h);
		this.maprx = this.w2h * this.mapry;
	}
	
	function MFish()
	{
		this.x = 0;
		this.y = 0;
		this.rad = 0;
		this.dir = new Point(1,1);
	}
	MFish.prototype.SetRad = function(r)
	{
		this.rad = r;
	}
	MFish.prototype.AddToRad = function(r)
	{
		this.rad += r;
	}
	MFish.prototype.SetDir = function(dx, dy)
	{
		this.dir.x = dx;
		this.dir.y = dy;
	}
	
	Model.around = function(n)
	{
		return (n * (0.75 + 1.2*Math.random()));
	}
	

	function Controller(wi, hi)
	{
		Resizable.apply(this);
		this.w = wi; this.h = hi;
		this.MARGIN = 20;
		this.paused = true;
		
		this.bg = new Background(wi, hi);
		this.addChild(this.bg);
		
		this.model = new Model();
		this.view = new View(this.model);
		this.addChild(this.view);
		
		this.topLength = 10;
		if(readCookie("topLength") != null) this.topLength = Math.floor(readCookie("topLength"));
		
		this.cln = new FlipNum(30, 0xffffff, "", " cm");
		this.addChild(this.cln);
		this.tln = new FlipNum(20, 0xffffff, "Top length: ", " cm");
		this.addChild(this.tln);
		this.tln.SetDirectly(this.topLength);
		
		this.addEventListener2(Event.ENTER_FRAME, this.onEF, this);
	}
	Controller.prototype = new Resizable();
	
	Controller.prototype.Start = function()
	{
		this.model.Reset();
		this.cln.SetDirectly(this.model.mfish.rad);
		this.UpdateViewScale();
		this.paused = false;
	}
	
	Controller.prototype.resize = function(wi, hi)
	{
		Resizable.prototype.resize.call(this, wi, hi);
		this.bg.resize(wi, hi);
		this.model.SetSizeRatio(wi/hi);
		this.view.x = 0.5*wi;
		this.view.y = 0.5*hi;
		this.tln.x = this.tln.y = this.MARGIN;
		this.cln.x = this.MARGIN;
		this.cln.y = this.MARGIN + 28;
		this.UpdateViewScale();
	}
	
	Controller.prototype.UpdateViewScale = function()
	{
		if(this.model.mapry == 0) return;
		var wi = this.w;  var hi = this.h;
		var sc = 0.5*hi/this.model.mapry;
		Tweener.addTween(this.view, {scaleX:sc, scaleY:sc, transition:"easeInOutSine", time:1 });
		this.bg.UpdateScale(sc);
	}
	
	Controller.prototype.onEF = function(e)
	{		
		if(this.paused) return;
		
		this.model.SetFishPos(this.view.mouseX, this.view.mouseY);
		this.model.Step();
		this.view.Update();
		
		var crad = this.model.mfish.rad;
		this.cln.SetNum(crad);
		
		if(crad>this.topLength)
		{
			this.topLength = crad;
			this.tln.SetNum(crad);
			createCookie("topLength", crad, 360);
		}
		
		if(this.model.IsOver())
		{
			this.paused = true;
			this.dispatchEvent(new Event("over"));
		}
		
		if(this.model.SizeChanged()) this.UpdateViewScale();
	}

	
	//-----   U T I L S   F O R   W O R K   W I T H   C O O K I E S
	
	function createCookie(name,value,days) {
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+"; path=/";
	}

	function readCookie(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	}

	function eraseCookie(name) {
		createCookie(name,"",-1);
	}


	function Panel()
	{
		Sprite.apply(this);
		
		//this.mouseChildren = false;
		this.hidden = false;
		
		var title = new Bitmap(new BitmapData("bf_pics/title.png"));
		this.addChild(title);
		
		var man1 = new CText("Eat fish that are smaller than you.", 3);
		var man2 = new CText("Avoid fish that are bigger than you.", 3);
		
		man1.x = 60; man2.x = 55;
		man1.y = 135; man2.y = 180;
		
		this.addChild(man1);
		this.addChild(man2);
		
		var vers = new CText("version 0.3", 2, 18);
		vers.x = 435; vers.y = 94;
		this.addChild(vers);
		
		this.pbtn = new Button("Play");
		this.pbtn.x = 230;
		this.pbtn.y = 250;
		this.addChild(this.pbtn);
	}
	Panel.prototype = new Sprite();
	
	Panel.prototype.Show = function(ny)
	{
		this.hidden = false;
		Tweener.addTween(this, {y:ny, time:0.5});
	}
	
	Panel.prototype.Hide = function(ny)
	{
		this.hidden = true;
		Tweener.addTween(this, {y:ny, time:0.5});
	}

	
	?
	function Fish()
	{
		Sprite.apply(this);
		
		this.mouseEnabled = false;
		this.mouseChildren = false;
		
		this.t = 0;
		this.v = 0;
		this.rad = 100;
		
		if(Fish.bodyTex == null)
		{
			Fish.bodyTex = new BitmapData("bf_pics/fish/body.png");
			Fish.eyesTex = new BitmapData("bf_pics/fish/eye.png");
			Fish.flipTex = new BitmapData("bf_pics/fish/flip.png");
		}
		
		this.body = new Bitmap(Fish.bodyTex);
		this.body.x = -180;
		this.body.y = -140;
		this.addChild(this.body);
		
		this.flip = new Bitmap(Fish.flipTex);
		this.flip.x = 20;
		this.flip.y = 45;
		this.addChild(this.flip);
		
		this.leye = new MBitmap(Fish.eyesTex, 5);
		this.reye = new MBitmap(Fish.eyesTex, 5);
		
		this.leye.x = 55; this.leye.y = -75;	this.leye.scaleX = this.leye.scaleY = 0.8;
		this.reye.x = 10; this.reye.y = -65;
		
		this.addChild(this.leye);
		this.addChild(this.reye);
		
		this.blinking = false;
		this.blinkI = 0;
	}
	Fish.prototype = new Sprite();
	
	Fish.prototype.update = function()
	{
		++this.t;
		
		this.flip.rotation = 60 + Math.sin( this.v * this.t/this.rad)*40;
			
		if(this.blinking)
		{
			var n = (this.blinkI<5) ? this.blinkI : (9 - this.blinkI);
			this.leye.gotoAndStop(n);
			this.reye.gotoAndStop(n);
			++this.blinkI;
			if(this.blinkI == 10)
			{
				this.blinking = false; 
				this.blinkI = 0;
			}
		}
		else this.blinking = Math.random()<0.02;
	}
	
	Fish.prototype.UpdateRadDir = function(rad, dirx)
	{
		if(rad == this.rad) return;
		this.v = 40*dirx/rad;
		this.rad = rad;
		var nsc = 0.01*this.rad;
		Tweener.addTween(this, {scaleX:((dirx<0)?-1:1)*nsc, scaleY:nsc, transition:"easeOutElastic", time:0.5});
	}
	function CText(t, p, s)
	{
		Sprite.apply(this);
		
		this.mouseChildren = false;
		if(!p) p = 2;
		if(!s) s = 26;
		
		this.tfr = new TextFormat("Trebuchet MS", s, 0xffffff);
		
		this.tf = new TextField();
		this.tf.setTextFormat(this.tfr);
		this.tf.text = t;
		this.tf.width = this.tf.textWidth
		this.tf.height = this.tf.textHeight;
		this.tf.x = this.tf.y = p;
		this.addChild(this.tf);
		
		this.pad = p;
		
		this.graphics.beginFill(0x000000, 0.4);
		this.graphics.drawRect(0, 0, this.tf.GetWidth()+2*p, this.tf.GetHeight()+2*p);
	}
	CText.prototype = new Sprite();
	
	CText.prototype.SetText = function(t)
	{
		this.tf.setText(t);
	}
	

	function FlipNum(s, c, pf, sf)	// size, color, prefix, suffix
	{
		Sprite.apply(this);
		
		if(s==null) s = 26;
		if(c==null) c = 0xffffff;
		if(pf==null) pf = "";
		if(sf==null) sf = "";
		
		this.prefix = pf;
		this.suffix = sf;
		this.cnum = -1; // current number
		this.tnum = -1; // target number
		
		this.tfr = new TextFormat("Trebuchet MS", s, c, true);
		
		this.tf = new TextField();
		this.tf.setTextFormat(this.tfr);
		this.SetDirectly(0);
		this.addChild(this.tf);
	}
	FlipNum.prototype = new Sprite();
	
	FlipNum.prototype.SetNum = function(n)
	{
		if(n == this.tnum) return;
		this.tnum = n;
		this.tf.text = this.prefix + n + this.suffix;
		this.tf.width = this.tf.textWidth; height = this.tf.textHeight;
		Tweener.addTween(this, {cnum:n, time:0.6, transition:"easeOutSine"});
		this.addEventListener2(Event.ENTER_FRAME, this.onEF, this);
	}
	
	FlipNum.prototype.SetDirectly = function(n)
	{
		if(n == this.tnum) return;
		this.tnum = this.cnum = n;
		this.tf.text = this.prefix + n + this.suffix;
		this.tf.width = this.tf.textWidth; height = this.tf.textHeight;
	}
	
	FlipNum.prototype.onEF = function(e)
	{
		if(this.cnum == this.tnum)
		{
			this.removeEventListener(Event.ENTER_FRAME, this.onEF, this);
		}
		var ntext = this.prefix + Math.floor(this.cnum) + this.suffix;
		if(ntext == this.tf.text) return;
		this.tf.text = ntext;
		this.tf.width = this.tf.textWidth; height = this.tf.textHeight;
	}
	

	function Button(text)
	{
		Sprite.apply(this);
	
		this.mouseChildren = false;
		this.buttonMode = true;
		this.tf = new TextField();
		this.tf.setTextFormat(Button.tfr);
		this.tf.text = text;
		this.tf.width = this.tf.textWidth;
		this.tf.height = this.tf.textHeight;
		this.tf.x = 8;
		this.tf.y = 4;
		this.addChild(this.tf);
		
		this.graphics.beginFill(0xffff7700);
		this.graphics.drawRect(0, 0, this.tf.GetWidth()+16, this.tf.GetHeight()+8);
	}
	Button.prototype = new Sprite();
	
	Button.tfr = new TextFormat("Trebuchet MS", 36, 0xffffff, true);